﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
using System.Text;
using System.Runtime.InteropServices;

/// <summary>
/// 字符串操作辅助类
/// </summary>
public class StringUtil
{
    #region 一些基本的符号常量

    /// <summary>
    /// 点符号 .
    /// </summary>
    public const string Dot = ".";

    /// <summary>
    /// 下划线 _
    /// </summary>
    public const string UnderScore = "_";

    /// <summary>
    /// 逗号加空格 , 
    /// </summary>
    public const string CommaSpace = ", ";

    /// <summary>
    /// 逗号 ,
    /// </summary>
    public const string Comma = ",";

    /// <summary>
    /// 左括号 (
    /// </summary>
    public const string OpenParen = "(";

    /// <summary>
    /// 右括号 )
    /// </summary>
    public const string ClosedParen = ")";

    /// <summary>
    /// 单引号 '
    /// </summary>
    public const string SingleQuote = "\'";

    /// <summary>
    /// 斜线 \
    /// </summary>
    public const string Slash = @"\";

    #endregion

    private StringUtil()
    {
    }


    /// <summary>
    /// 移除最后的字符
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string RemoveFinalChar(string s)
    {
        if (s.Length > 1)
        {
            s = s.Substring(0, s.Length - 1);
        }
        return s;
    }

    /// <summary>
    /// 移除最后的逗号
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string RemoveFinalComma(string s)
    {
        if (s.Trim().Length > 0)
        {
            int c = s.LastIndexOf(",");
            if (c > 0)
            {
                s = s.Substring(0, s.Length - (s.Length - c));
            }
        }
        return s;
    }

    /// <summary>
    /// 移除字符中的空格
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string RemoveSpaces(string s)
    {
        s = s.Trim();
        s = s.Replace(" ", "");
        return s;
    }

    /// <summary>
    /// 判断字符是否NULL或者为空
    /// </summary>
    public static bool IsNullOrEmpty(string value)
    {
        if (value == null || value == string.Empty)
        {
            return true;
        }

        return false;
    }


        #region 字体转换
        enum Language
        {
           SIMPLIFIED_CHINESE = 0x02000000,
           TRADITIONAL_CHINESE = 0x04000000,
        }
        [DllImport("kernel32.dll", EntryPoint = "LCMapStringA")]
        static extern int LCMapString(int Locale, int dwMapFlags, byte[] lpSrcStr, int cchSrc, byte[] lpDestStr, int cchDest);
        /// <summary>
        /// 繁体转简体API
        /// </summary>
        /// <param name="str">内容</param>
        /// <returns></returns>
        public static string BigToGb2312Ex(string str)
        {
          
            byte[] src = Encoding.Default.GetBytes(str);
            byte[] dest = new byte[src.Length];
            LCMapString(0x0804, Language.SIMPLIFIED_CHINESE.GetHashCode(), src, -1, dest, src.Length);
            return Encoding.Default.GetString(dest);

        }


        /// <summary>
        /// 简体转繁体API
        /// </summary>
        /// <param name="str">内容</param>
        /// <returns></returns>
        public static string Gb2312ToGigEx(string str)
        {

            byte[] src = Encoding.Default.GetBytes(str);
            byte[] dest = new byte[src.Length];
            LCMapString(0x0804, Language.TRADITIONAL_CHINESE.GetHashCode(), src, -1, dest, src.Length);
            return Encoding.Default.GetString(dest);
        }
        /// <summary>
        /// 繁体转简体
        /// </summary>
        /// <param name="str">内容</param>
        /// <returns></returns>
        public static string BigToGb2312(string str)
        {
            return Microsoft.VisualBasic.Strings.StrConv(str, Microsoft.VisualBasic.VbStrConv.SimplifiedChinese, 0);
        }


        /// <summary>
        /// 简体转繁体
        /// </summary>
        /// <param name="str">内容</param>
        /// <returns></returns>
        public static string Gb2312ToGig(string str)
        {
            return Microsoft.VisualBasic.Strings.StrConv(str, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, 0);
        }

        #endregion

        #region 全角 半角 互转换
        /**///// <summary>
        /// 转全角的函数(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>        
        public static string ToSDC(string input)
        {
            //半角转全角：
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }
        /// <summary>
        /// 转半角的函数(DBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToDSC(string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }
        #endregion

        #region 字符串判断
        /// <summary>
        /// 根据传入字符串判断是否是数字（正整数）
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>  
        public static bool IsNumeric(string str)
        {
            System.Text.RegularExpressions.Regex reg1
                = new System.Text.RegularExpressions.Regex(@"^\d*$");
            return reg1.IsMatch(str);
        }


        /// <summary>
        /// 根据传入字符串判断是否是日期
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>  
        public static bool IsDateTime(string str)
        {
            System.Text.RegularExpressions.Regex reg1
                = new System.Text.RegularExpressions.Regex(@"^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$");
            return reg1.IsMatch(str);
        }

        /// <summary>
        /// 判断字符或字符串里是否有汉字
        /// </summary>
        /// <param name="CString"></param>
        /// <returns></returns>
        public static bool IsChina(string CString)
        {
            bool BoolValue = false;
            for (int i = 0; i < CString.Length; i++)
            {
                if (Convert.ToInt32(Convert.ToChar(CString.Substring(i, 1))) < Convert.ToInt32(Convert.ToChar(128)))
                {
                    BoolValue = false;
                }
                else
                {
                    BoolValue = true;
                }
            }
            return BoolValue;
        }

        #endregion 字符串判断

        #region 字符串操作
        /// <summary>
        /// 由16进制转为汉字字符串（如：B2E2 -> 测 ）
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string ConvertHexToString(string source)
        {
            byte[] oribyte = new byte[source.Length / 2];
            for (int i = 0; i < source.Length; i += 2)
            {
                string str = Convert.ToInt32(source.Substring(i, 2), 16).ToString();
                oribyte[i / 2] = Convert.ToByte(source.Substring(i, 2), 16);
            }
            return System.Text.Encoding.Default.GetString(oribyte);
        }

        /// <summary>
        /// 字符串转为16进制字符串（如：测 -> B2E2 ）
        /// </summary>
        /// <param name="Word"></param>
        /// <returns></returns>
        public static string ConvertToHex(string Word)
        {
            int i = Word.Length;
            string temp;
            string end = "";
            byte[] array = new byte[2];
            int i1, i2;
            for (int j = 0; j < i; j++)
            {
                temp = Word.Substring(j, 1);
                array = System.Text.Encoding.Default.GetBytes(temp);
                if (array.Length.ToString() == "1")
                {
                    i1 = Convert.ToInt32(array[0]);
                    end += Convert.ToString(i1, 16);
                }
                else
                {
                    i1 = Convert.ToInt32(array[0]);
                    i2 = Convert.ToInt32(array[1]);
                    end += Convert.ToString(i1, 16);
                    end += Convert.ToString(i2, 16);
                }
            }
            return end.ToUpper();
        }

        /// <summary>
        /// 中文字符串转为拼间首字母串
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>
        public static string GetChineseSpell(string strText)
        {
            int len = strText.Length;
            StringBuilder myStr = new StringBuilder();
           
            for (int i = 0; i < len; i++)
            {
                myStr.Append( GetSpell(strText.Substring(i, 1)));
            }
            return myStr.ToString();
        }

        /// <summary>
        /// 中文字符转为拼间首字母
        /// </summary>
        /// <param name="cnChar"></param>
        /// <returns></returns>
        public static string GetSpell(string cnChar)
        {
            byte[] arrCN = Encoding.Default.GetBytes(cnChar);
            if (arrCN.Length > 1)
            {
                int area = (short)arrCN[0];
                int pos = (short)arrCN[1];
                int code = (area << 8) + pos;
                int[] areacode = { 45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481 };
                for (int i = 0; i < 26; i++)
                {
                    int max = 55290;
                    if (i != 25) max = areacode[i + 1];
                    if (areacode[i] <= code && code < max)
                    {
                        return Encoding.Default.GetString(new byte[] { (byte)(65 + i) });
                    }
                }
                return "*";
            }
            else return cnChar;
        }

        /// <summary>
        /// 获取字符串某项的值
        /// </summary>
        /// <param name="BescString">字符串</param>
        /// <param name="itemName">键名</param>
        /// <returns>项目值</returns>
        public static string GetItemValueString(string BeseString, string itemName)
        {
            if (!BeseString.EndsWith(";"))
                BeseString += ";";

            // \s* 匹配0个或多个空白字符
            // .*? 匹配0个或多个除 "\n" 之外的任何字符(?指尽可能少重复)
            string regexStr = itemName + @"\s*=\s*(?<key>.*?);";
            System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(regexStr, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Match mc = r.Match(BeseString);
            return mc.Groups["key"].Value;
        }

        /// <summary>
        /// 获取字符串指定两个字符中间的值,正则
        /// </summary>
        /// <param name="BeseString">字符串</param>
        /// <param name="StartString">开始字符串</param>
        /// <param name="EndString">结束字符串</param>
        /// <returns>项目值</returns>
        public static string GetStringMiddleEx(string BeseString, string StartString, string EndString)
        {

            try
            {
                // \s* 匹配0个或多个空白字符
                // .*? 匹配0个或多个除 "\n" 之外的任何字符(?指尽可能少重复)
                string regexStr = StartString + @"\s*(?<key>.*?)" + EndString;
                System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(regexStr, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Match mc = r.Match(BeseString);
                return mc.Groups["key"].Value;
            }
            catch (Exception)
            {
               return  GetStringMiddle(BeseString,  StartString,  EndString);

            }
        }


      
        /// <summary>
        /// 小号转大写
        /// </summary>
        /// <param name="strN"></param>
        /// <returns></returns>
        public static string NumberToCn(string strN)
        {
            string[] strNum = { "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
            int bl = -1;
            bool ch = true;
            int len = strN.Length;
            if (len > 24)
            {
                Console.WriteLine("您输入的数字过大，无法转换！");
                return "";
            }
            string strResult = "";
            string[] strSZ = new string[len];
            for (int i = 0; i < len; i++)
            {
                strSZ[i] = strN.Substring(i, 1);
                if (!System.Text.RegularExpressions.Regex.IsMatch(strSZ[i], "^[0-9]$"))
                {
                    Console.WriteLine("您输入的数字含有非数字符号！");
                    return "";
                }
                if (strSZ[0] == "0" && ch)//检验首位出现零的情况
                {
                    if (i != len - 1 && strSZ[i] == "0" && strSZ[i + 1] != "0")
                        bl = i;
                    else
                        ch = false;
                }
            }
            for (int i = 0; i < len; i++)
            {
                int num = len - i;
                if (strSZ[i] != "0")
                {
                    strResult += strNum[Convert.ToInt32(strSZ[i]) - 1];//将阿拉伯数字转换成中文大写数字
                    //加上单位
                    if (num % 4 == 2)
                        strResult += "拾";
                    if (num % 4 == 3)
                        strResult += "佰";
                    if (num % 4 == 0)
                        strResult += "仟";
                    if (num % 4 == 1)
                    {
                        if (num / 4 == 1)
                            strResult += "萬";
                        if (num / 4 == 2)
                            strResult += "亿";
                        if (num / 4 == 3)
                            strResult += "萬";
                        if (num / 4 == 4)
                            strResult += "亿";
                        if (num / 4 == 5)
                            strResult += "萬";
                    }
                }
                else
                {
                    if (i > bl)
                    {
                        if ((i != len - 1 && strSZ[i + 1] != "0" && (num - 1) % 4 != 0))
                        {
                            //此处判断“0”不是出现在末尾，且下一位也不是“0”；
                            //如 10012332 在此处读法应该为壹仟零壹萬贰仟叁佰叁拾贰,两个零只要读一个零
                            strResult += "零";
                        }
                        if (i != len - 1 && strSZ[i + 1] != "0")
                        {
                            switch (num)
                            {
                                //此处出现的情况是如 10002332，“0”出现在万位上就应该加上一个“萬”读成壹仟萬零贰仟叁佰叁拾贰
                                case 5: strResult += "萬";
                                    break;
                                case 9: strResult += "亿";
                                    break;
                                case 13: strResult += "萬";
                                    break;
                            }
                        }
                        if (i != len - 1 && strSZ[i + 1] != "0" && (num - 1) % 4 == 0)
                        {
                            //此处出现的情况是如 10002332，“0”出现在万位上就应该加上一个“零”读成壹仟萬零贰仟叁佰叁拾贰
                            strResult += "零";
                        }
                    }
                }
            }
            return strResult;
        }


        /// <summary>
        /// 身份证验证15位18位
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        private bool CheckIDCard(string Id)
        {
            if (Id.Length == 18)
            {
                bool check = CheckIDCard18(Id);
                return check;
            }
            else if (Id.Length == 15)
            {
                bool check = CheckIDCard15(Id);
                return check;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 身份证验证18位
        /// 第16位 % 2 == 1 ? "男" : "女";
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        private bool CheckIDCard18(string Id)
        {
            long n = 0;
            if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
            string[] Wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
            char[] Ai = Id.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += int.Parse(Wi[i]) * int.Parse(Ai[i].ToString());
            }
            int y = -1;
            Math.DivRem(sum, 11, out y);
            if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
            {
                return false;//校验码验证
            }
            return true;//符合GB11643-1999标准
        }

        /// <summary>
        /// 身份证验证15位
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        private bool CheckIDCard15(string Id)
        {
            long n = 0;
            if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
            {
                return false;//数字验证
            }
            string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            return true;//符合15位身份证标准
        }



        /// <summary>
        /// 根据传入出生日期字符串判断当前年龄
        /// </summary>
        /// <param name="birthday"></param>
        /// <returns></returns>        
        public static int GetAge(DateTime birthday)
        {
            int year = System.DateTime.Now.Year;
            int month = System.DateTime.Now.Month;
            int day = System.DateTime.Now.Day;
            int year1 = birthday.Year;
            int month1 = birthday.Month;
            int day1 = birthday.Day;
            int Age = year + month / 12 + day / 365 - year1 - month1 / 12 - day1 / 365;
            return Age;
        }

        /// <summary>
        /// 字符串颠倒输出
        /// </summary>
        /// <param name="str1"></param>
        /// <returns></returns>
        public static string StringUpsideDown(string str1)
        {

            char[] charstr = str1.ToCharArray();
            Array.Reverse(charstr);
            return new string(charstr);
        }

        /// <summary>
        /// 取字符串中的数字
        /// </summary>
        /// <param name="str1">字符串</param>
        /// <returns></returns>
        public static string GetStringNumber(string str1)
        {
            System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(@"[^\d]");
            return re.Replace(str1, "");
        }


        /// <summary>
        /// 根据字符按字符串分段
        /// </summary>
        /// <param name="BaseStr">字符串</param>
        /// <param name="Separtor">分隔字符</param>
        /// <returns></returns>
        public static string[] StringSplit(string BaseString, string Separtor)
        {
            return BaseString.Split(new string[] { Separtor }, StringSplitOptions.None);
           
        }



        /// <summary>
        /// 返回字符串 指定 两个字符串中间的信息
        /// </summary>
        /// <param name="BaseString">字符串</param>
        /// <param name="StartString">开始段</param>
        /// <param name="EndString">尾段</param>
        /// <returns></returns>
        public static string GetStringMiddle(string BaseString, string StartString, string EndString)
        {

            if (BaseString.IndexOf(StartString) == -1) return "";
            if (BaseString.IndexOf(EndString) == -1) return "";

            string LastPart = BaseString.Substring(BaseString.IndexOf(StartString) + StartString.Length);

            if (LastPart.IndexOf(EndString) == -1) return "";


            return LastPart.Substring(0, LastPart.IndexOf(EndString));


        }

        /// <summary>
        /// 两字符串相加以字符隔开
        /// </summary>
        /// <param name="String1">字符串1</param>
        /// <param name="String2">字符串2</param>
        /// <param name="CharActer">隔离字符</param>
        /// <returns></returns>
        private string AddStr1Str2(string String1, string String2, string CharActer)
        {
            if (String1.Length > 0)
                return String1 + CharActer + String2;
            else
                return String2;
           
        }


        #endregion 字符串操作

    }